package com.dycong.common.json;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class JsonUtil_easyUi {

	static SerializerFeature[] serializerFeature={
			SerializerFeature.WriteDateUseDateFormat,
			SerializerFeature.DisableCircularReferenceDetect,
			SerializerFeature.QuoteFieldNames,
			SerializerFeature.WriteNullStringAsEmpty,
			SerializerFeature.WriteMapNullValue,
			SerializerFeature.WriteNullBooleanAsFalse,
			SerializerFeature.WriteNullNumberAsZero,
			SerializerFeature.WriteNullListAsEmpty
	} ;

	static SerializerFeature[] serializerFeature_={
			SerializerFeature.WriteDateUseDateFormat,
			SerializerFeature.BrowserCompatible,
			SerializerFeature.DisableCircularReferenceDetect,
			SerializerFeature.QuoteFieldNames,
			SerializerFeature.WriteNullStringAsEmpty,
			SerializerFeature.WriteMapNullValue,
			SerializerFeature.WriteNullBooleanAsFalse,
			SerializerFeature.WriteNullNumberAsZero,
			SerializerFeature.WriteNullListAsEmpty
	} ;

	private static final Logger logger=Logger.getLogger(JsonUtil_easyUi.class);
	/**
	 * 将对象转换成JSON字符串，并响应回前台
	 *
	 * @param object
	 * @param includesProperties
	 *            需要转换的属性
	 * @param excludesProperties
	 *            不需要转换的属性
	 */
	public static void writeJsonByFilter(Object object, HttpServletRequest request, HttpServletResponse response, String[] includesProperties, String[] excludesProperties) {
		writeJsonByFilter(object, request, response, new MySerializeConfig(null), includesProperties, excludesProperties);
	}

	/**
	 * 将对象转换成JSON字符串，并响应回前台
	 *
	 * @param object
	 * @param includesProperties
	 *            需要转换的属性
	 * @param excludesProperties
	 *            不需要转换的属性
	 */
	public static void writeJsonByFilter(Object object, HttpServletRequest request, HttpServletResponse response, MySerializeConfig cfg, String[] includesProperties, String[] excludesProperties) {
		try {
			SimpleJsonFilter filter = new SimpleJsonFilter();// excludes优先于includes
			if (excludesProperties != null && excludesProperties.length > 0) {
				filter.getExcludes().addAll(Arrays.<String> asList(excludesProperties));
			}
			if (includesProperties != null && includesProperties.length > 0) {
				filter.getIncludes().addAll(Arrays.<String> asList(includesProperties));
			}

//			logger.debug("对象转JSON：要排除的属性[" + excludesProperties + "]要包含的属性[" + includesProperties + "]");
			String json;
			String User_Agent = request.getHeader("User-Agent");
//			, SerializerFeature.DisableCircularReferenceDetect
			if (StringUtils.indexOfIgnoreCase(User_Agent, "MSIE 6") > -1) {
				// 使用SerializerFeature.BrowserCompatible特性会把所有的中文都会序列化为\\uXXXX这种格式，字节数会多一些，但是能兼容IE6
				json = JSON.toJSONString(object,cfg,filter,serializerFeature);
			} else {
				// 使用SerializerFeature.WriteDateUseDateFormat特性来序列化日期格式的类型为yyyy-MM-dd hh24:mi:ss
				// 使用SerializerFeature.DisableCircularReferenceDetect特性关闭引用检测和生成
				json = JSON.toJSONString(object,cfg,filter,serializerFeature_);
			}
//			logger.info("转换后的JSON字符串：" + json);
			response.setContentType("text/html;charset=utf-8");
			response.getWriter().write(json);
			response.getWriter().flush();
			response.getWriter().close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static <T> T toObject(String json, Class<T> clazz) {
		try {
			ObjectMapper objectMapper = new ObjectMapper();
			return objectMapper.readValue(json.getBytes("UTF-8"), clazz);
		} catch (RuntimeException | IOException e) {
			logger.info("parsing json to Object error, json is: " + json);
			logger.debug("", e);
			return  null;
		}
	}

	public static Map<String, Object> toObject(String json){
		return toObject(json, HashMap.class);
	}

	public static String toJson(Object object) {
		if (object == null) {
			return null;
		}
		if(object instanceof String){
			return object.toString();
		}
		ObjectMapper objectMapper = new ObjectMapper();
		try (ByteArrayOutputStream out = new ByteArrayOutputStream();) {
			objectMapper.writeValue(out, object);
			String json = out.toString("UTF-8");
			return json;
		} catch (IOException | RuntimeException e) {
			logger.warn("parse json error", e);
			return null;
		}
	}

	public static <T> T convertValue(Object from , Class<T> to){
		ObjectMapper objectMapper = new ObjectMapper();
		return objectMapper.convertValue(from, to);
	}
}
